#include <gl/glut.h>

#include <stdlib.h>
#include <stdio.h>

#include "glm.h"

#define WINDOW_WIDTH (600)
#define WINDOW_HEIGHT (400)

int window = 0;
float	g_cameraXPos = 100.0f;
float	g_cameraYPos = 100.0f;
float	g_cameraZPos = 200.0f;

GLMmodel*	g_modelPtr = NULL;
float	g_modelRotX = 0;
float	g_modelRotY = 0;
float	g_modelRotZ = 0;

void on_key_press(unsigned char key, int x, int y);
void scene_render(void);
void on_idle(void);
void init();
void reshape(int width, int height);

int main(int argc, char *argv[])
{
	glutInit (&argc, argv);
	glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize (WINDOW_WIDTH, WINDOW_HEIGHT);

	window = glutCreateWindow (argv[0]);

	glutDisplayFunc (scene_render);
	glutKeyboardFunc (on_key_press);
	glutIdleFunc (on_idle);
	glutReshapeFunc(reshape);

	init();

	glutMainLoop();
}

void init()
{
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glEnable(GL_SMOOTH);
	
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);

	// g_modelPtr = glmReadOBJ("./data/0100001_3D_M.obj");		// middle level
	g_modelPtr = glmReadOBJ("./data/0100001_3D_L.obj");			// low level
}

void scene_render()
{
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	
	glPushMatrix();
	
	// glutSolidCube(50.0f);
	glRotatef(g_modelRotX, 1,0,0);
	glRotatef(g_modelRotY, 0,1,0);
	glRotatef(g_modelRotZ, 0,0,1);

	if (g_modelPtr)
	{
		glmDraw(g_modelPtr, GLM_TEXTURE);
	}

	glPopMatrix();

	glutSwapBuffers();

}

void reshape(int width, int height)
{
	glViewport(0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, (GLdouble)width / (GLdouble)height, 0.1, 1000.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(g_cameraXPos, g_cameraYPos, g_cameraZPos, 0,0,0, 0,1,0);
}

void on_idle(void)
{
}

void on_key_press(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 27:
		if (g_modelPtr)
		{
			glmDelete(g_modelPtr);
			g_modelPtr = 0;
		}
		exit(0);
	case 'y':
		g_modelRotY += 4.0f;
		if (g_modelRotY > 360.0f)
		{
			g_modelRotY = 0.0f;
		}
		break;
	case 'Y':
		g_modelRotY -= 4.0f;
		if (g_modelRotY <= 0.0f)
		{
			g_modelRotY = 360.0f;
		}
		break;
	case 'x':
		g_modelRotX += 4.0f;
		if (g_modelRotX > 360.0f)
		{
			g_modelRotX = 0.0f;
		}
		break;
	case 'X':
		g_modelRotX -= 4.0f;
		if (g_modelRotX <= 0.0f)
		{
			g_modelRotX = 360.0f;
		}
		break;
	case 'z':
		g_modelRotZ += 4.0f;
		if (g_modelRotZ > 360.0f)
		{
			g_modelRotZ = 0.0f;
		}
		break;
	case 'Z':
		g_modelRotZ -= 4.0f;
		if (g_modelRotZ <= 0.0f)
		{
			g_modelRotZ = 360.0f;
		}
		break;
	}

	glutPostRedisplay();

}